﻿using System;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Workflow;
using Grauers_set_metadata_properties.Grauers;

namespace Grauers_set_metadata_properties.Grauers_metadata_properties_handler
{
    
    public class Grauers_metadata_properties_handler : SPItemEventReceiver
    {
        private static string DefaultColumnName = "Issue";
        private static string SiteOptionSetting_ColumnName = "GrauersMetadataProperties_Store";
        DocumentPropertyItem dpi = new DocumentPropertyItem();        

        /// <summary>
        /// An item was updated.
        /// </summary>
        public override void ItemUpdated(SPItemEventProperties properties)
        {
            CheckUpdate(properties, "ItemUpdated");            
        }

        /// <summary>
        /// An item was checked in.
        /// </summary>
        public override void ItemCheckedIn(SPItemEventProperties properties)
        {
            CheckUpdate(properties, "ItemCheckedIn");
        }

        /// <summary>
        /// An item was checked out.
        /// </summary>
        public override void ItemCheckedOut(SPItemEventProperties properties)
        {
            CheckUpdate(properties, "ItemCheckedOut");
        }

        /// <summary>
        /// An item was unchecked out.
        /// </summary>
        public override void ItemUncheckedOut(SPItemEventProperties properties)
        {
            CheckUpdate(properties, "ItemUncheckedOut");
        }

        #region Private functions
        /// <summary>
        /// Return true if the version should be updated for the specified item.
        /// </summary>
        /// <param name="evprop"></param>
        /// <returns></returns>
        private bool IsApplicable(SPItemEventProperties evprop, string columnName)
        {
            bool isLink = evprop.ListItem.ContentTypeId.IsChildOf(SPBuiltInContentTypeId.LinkToDocument);
            return !isLink && evprop.List.Fields.ContainsField(columnName) && evprop.List.EnableVersioning;
        }

        /// <summary>
        /// Return the column name that should be used, either as specified as a Site Option or the default.
        /// </summary>
        /// <param name="evprop"></param>
        /// <returns></returns>
        private string GetColumnName(SPItemEventProperties evprop)
        {
            object ovalue = evprop.Web.AllProperties[SiteOptionSetting_ColumnName];
            return ovalue != null ? ovalue.ToString() : DefaultColumnName;
        }

        /// <summary>
        /// Update the corresponding field with the current version.
        /// </summary>
        /// <param name="item"></param>
        private void UpdateIssue(SPListItem item, string columnName)
        {
            EventFiringEnabled = false;
            try
            {
                if (item[columnName] == null || item[columnName].ToString() != item[SPBuiltInFieldId._UIVersionString].ToString())
                {
                    item[columnName] = item[SPBuiltInFieldId._UIVersionString];
                    item.SystemUpdate();
                }
            }
            catch (Exception err)
            {
                //LogHelper.LogError("UpdateIssue", err);
            }
            finally
            {
                EventFiringEnabled = true;
            }
        }

        /// <summary>
        /// Common method for multiple events where the version update is checked and, if applicable, performed.
        /// </summary>
        /// <param name="properties"></param>
        private void CheckUpdate(SPItemEventProperties properties, string operationNameForErrorReport)
        {
            try
            {
                dpi = DocumentPropertyBusinessLayer.GetBy_LibraryName(properties.ListTitle, properties.Web);

                SPListItem item = properties.ListItem;

                #region Issue
                if (IsApplicable(properties, dpi.Issue))
                {                                        
                    UpdateIssue(item, dpi.Issue);
                }
                #endregion

                #region Approved date
                if (IsApplicable(properties, dpi.ApprovedDate))
                {
                    // Dokumentet godkändes
                    if (IsApprovedEvent(properties))
                    {
                        EventFiringEnabled = false;
                        if (item.Fields[dpi.ApprovedDate].Type == SPFieldType.Text)
                            item[dpi.ApprovedDate] = DateTime.Now.ToString();
                        else if (item.Fields[dpi.ApprovedDate].Type == SPFieldType.DateTime)
                            item[dpi.ApprovedDate] = DateTime.Now;
                        item.SystemUpdate();
                        EventFiringEnabled = true;
                    }
                    // Dokumentet godkändes ej
                    else if (IsUnapprovedEvent(properties))
                    {
                        EventFiringEnabled = false;
                        item.Properties[dpi.ApprovedDate] = null;
                        item.SystemUpdate();
                        EventFiringEnabled = true;
                    }
                }
                #endregion

                #region Approved by
                if (IsApplicable(properties, dpi.ApprovedBy))
                {
                    // Dokumentet godkändes
                    if (IsApprovedEvent(properties))
                    {
                        EventFiringEnabled = false;
                        // Kolumnen är av typ text
                        if (item.Fields[dpi.ApprovedBy].Type == SPFieldType.Text)
                        {
                            item[dpi.ApprovedBy] = properties.Web.CurrentUser.Name;
                        }
                        // Kolumnen är av typ User
                        else if (item.Fields[dpi.ApprovedBy].Type == SPFieldType.User)
                        {
                            SPUser user = properties.Web.CurrentUser;
                            item[dpi.ApprovedBy] = user;
                        }
                        item.SystemUpdate();
                        EventFiringEnabled = true;
                    }
                    // Dokumentet godkändes ej
                    else if (IsUnapprovedEvent(properties))
                    {
                        EventFiringEnabled = false;
                        item.Properties[dpi.ApprovedBy] = null;
                        item.SystemUpdate();
                        EventFiringEnabled = true;
                    }
                }
                #endregion

            }
            catch (Exception err)
            {
                //LogHelper.LogError(operationNameForErrorReport, err);
            }
        }

        private static bool IsApprovedEvent(SPItemEventProperties properties)
        {
            object before = properties.BeforeProperties["vti_doclibmodstat"];
            object after = properties.AfterProperties["vti_doclibmodstat"];

            return after != null && after.ToString() == "0" && (before == null || before.ToString() != "0");
        }

        private static bool IsUnapprovedEvent(SPItemEventProperties properties)
        {
            object before = properties.BeforeProperties["vti_doclibmodstat"];
            object after = properties.AfterProperties["vti_doclibmodstat"];

            return after != null && after.ToString() == "2" && before != null && before.ToString() == "0";
        }
        #endregion

    }
}